package experiments;

import java.io.File;
import java.io.FileNotFoundException;
import java.util.Scanner;

import model.Field;
import model.OthelloBoard;
import neuralnetworks.MultiLayerPerceptron;

import players.*;

public class Competition {

	Player[] players;
	Player initializer = new RandomPlayer();
	String[] info;
	
	int testing_games = 1000;
	
	int[][] winsPlayer1;
	
	public Competition(String[] args) throws FileNotFoundException
	{
		players = new Player[args.length + 4]; 
		players[0] = new RandomPlayer();
		players[1] = new PositionalPlayer();
		players[2] = new MinimaxPlayer(new PositionalPlayer(), 2);
		players[3] = new MobilityPlayer();
		
		info = new String[args.length + 4];
		info[0] = info[1] = info[2] = info[3] = "";
		
		//read networks from each file
		for(int i = 0; i < args.length; i++)
		{
			Scanner sc = new Scanner(new File(args[i]));
			
			MultiLayerPerceptron[] utilities = new MultiLayerPerceptron[sc.nextInt()];
			for(int k = 0; k < utilities.length; k++) //single player can have more networks
				utilities[k] = new MultiLayerPerceptron(sc);
			
			players[4 + i] = new NeuralNetworkPlayer(utilities, null);
			
			String[] inf = args[i].split("/");
			info[4 + i] = inf[inf.length-1];
		}
		
		//get results
		playoff();
		
		//show results
		System.out.print("\t");
		for(int p2 = 0; p2 < players.length; p2++)
			System.out.print(p2 + "\t");
		System.out.println();
		for(int p1 = 0; p1 < players.length; p1++)
		{
			System.out.print(p1 + ":\t");
			for(int p2 = 0; p2 < players.length; p2++)
			{
				System.out.print(winsPlayer1[p1][p2] + "\t");
			}
			System.out.println();
		}
		for(int p2 = 0; p2 < players.length; p2++)
			System.out.println(p2 + ": " + players[p2] + " " + info[p2]);
	}
	
	private void playoff()
	{
		winsPlayer1  = new int[players.length][players.length];
		
		for(int p1 = 0; p1 < players.length; p1++)
			for(int p2 = 0; p2 <= p1; p2++)
			{
				System.out.print(players[p1] + " " + info[p1] + " vs. " + players[p2] + " " + info[p2]);
				long start = System.currentTimeMillis();
				
				int[] scores = testPlayers(players[p1], players[p2]);
				winsPlayer1[p1][p2] = scores[Field.WHITE];
				winsPlayer1[p2][p1] = scores[Field.BLACK];
				
				long stop = System.currentTimeMillis();
				System.out.println(" (" + scores[Field.WHITE] + " - " + scores[Field.BLACK] + " @ " + (stop - start)/1000.0 + " sec)");
			}
	}
	
	private int[] testPlayers(Player whitePlayer, Player blackPlayer)
	{
		int initial_test_moves = 4;
		
		//wins for white, black or nobody
		int[] wins = new int[3];
		
		OthelloBoard board = new OthelloBoard();
		for(int trial = 0; 2 * trial < testing_games; trial++)
        {
        	board.reset();
        	for(int i = 0; i < initial_test_moves; i++)
        	{// fixed on 4 initial random moves per player
        		initializer.move(board, Field.WHITE);
        		initializer.move(board, Field.BLACK);
        	}
        	//play the game
	        boolean whiteCouldMove = true, blackCouldMove = true;
	        while(whiteCouldMove || blackCouldMove)
	        {
	        	whiteCouldMove = whitePlayer.move(board, Field.WHITE);
	        	blackCouldMove = blackPlayer.move(board, Field.BLACK);
	        }
	        wins[board.bestPlayer()]++;
        }
		//switch starting positions:
		for(int trial = 0; 2 * trial < testing_games; trial++)
        {
        	board.reset();
        	for(int i = 0; i < initial_test_moves; i++)
        	{
        		initializer.move(board, Field.BLACK);
        		initializer.move(board, Field.WHITE);
        	}
        	//play the game
	        boolean whiteCouldMove = true, blackCouldMove = true;
	        while(whiteCouldMove || blackCouldMove)
	        {
	        	blackCouldMove = blackPlayer.move(board, Field.BLACK);
	        	whiteCouldMove = whitePlayer.move(board, Field.WHITE);
	        }
	        wins[board.bestPlayer()]++;
        }
		return wins;
	}
	
	public static void main(String[] args) throws FileNotFoundException 
	{//args contains filenames of neural networks to test
     //by default test against eachother and random/positional/mobility
		new Competition(args);
	}

}
